import { ElMessage } from "element-plus";
import router from "./router";
import { useUserStore } from "./stores/user";
import type { RouteLocationNormalized, RouteRecordRaw } from "vue-router";
import { getLocalToken } from "./utils/auth";
import { getProfileAPI } from "./apis/user";
import { asyncRoutes } from "./router/asyncRoutes";
import { useMenuStore } from "./stores/menu";


/**
 * 处理一级路由
 */
const getFirstRoutePerms = (permissions: string[]) => {
  // 提取一级路由菜单
  const tempArr = permissions.map((item) => item.split(':')[0])
  // 数组去重
  return Array.from(new Set(tempArr))
}

// 处理二级路由权限数据
const getSecondRoutePerms = (permsArr: string[]) => {
  const newArr = permsArr.map(item => {
    const arr = item.split(':')
    return `${arr[0]}:${arr[1]}`
  })
  return Array.from(new Set(newArr))
}


// 根据权限筛选出匹配的路由
const getRoutes = (
  firstRoutePerms: string[],  // 一级路由权限集合
  secondRoutePerms: string[], // 二级路由权限集合
  asyncRoutes: RouteRecordRaw[] // 所有的动态路由数据
) => {
  if (firstRoutePerms.includes('*')) {
    // 管理员（拷贝 - 防止重复登录同一个用户时，此变量值返回给外面后不断 push * 地址，导致左侧菜单 key 重复报错问题）
    return [...asyncRoutes]
  }
  // 过滤出一级路由
  const firstRoutes = asyncRoutes.filter(route => {
    return firstRoutePerms.includes(route.meta!.permission!)
  })
  // 基于筛选的一级路由，继续筛选二级路由
  const lastRoutes = firstRoutes.map(route => {
    return {
      ...route,
      // 筛选二级路由
      children: route.children?.filter(v => secondRoutePerms.includes(v.meta!.permission!))
    }
  })
  return lastRoutes
}



// 白名单
const WHITE_LIST = ["/login", "/404"];
// 路由导航守卫
router.beforeEach(async (to, from, next) => {
  //获取token
  const store = useUserStore();
  // 判断是否有 token
  if (store.token) {
    // 如果没有用户信息，发送请求获取，并保存到 store 中
    if (!store.profile.id) {
      const res = await getProfileAPI()
      store.setProfile(res.data)
      const menus = getFirstRoutePerms(res.data.permissions)
      const smenus = getSecondRoutePerms(res.data.permissions)

      // console.log('menus', menus);
      // console.log('smenus', smenus);

      // 1. 获取匹配的路由
      const perRoutes = getRoutes(menus, smenus, asyncRoutes)
      // 2. 遍历匹配的路由，动态添加到路由表中
      perRoutes.forEach(route => {
        // 动态添加路由
        router.addRoute(route as RouteRecordRaw)
      })

      // 3. 保存侧栏菜单路由
      const menuStore = useMenuStore()
      menuStore.setMenuList(perRoutes as RouteRecordRaw[])

      // 动态添加路由后的固定用法
      next({ ...to })
    } else {
      // 有 token，放行
      next()
    }
  } else {
    // 是否在白名单中
    if (WHITE_LIST.includes(to.path)) {
      // 在白名单中，放行
      next()
    } else {
      // 不在白名单中，跳转到登录页
      next("/login");
      ElMessage.warning('登录信息无效，请先登录')
    }
  }
})

// 路由导航守卫
router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next) => {
  // 获取用户状态管理实例
  const store = useUserStore();
  // 获取当前用户的token
  const token = getLocalToken();

  // 检查即将访问的路由是否需要身份验证
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // 如果用户没有登录（没有token）
    if (!token) {
      // 存储目标页面的路径
      localStorage.setItem('redirectPath', to.fullPath);
      // 重定向用户到登录页面
      next('/login');
      ElMessage.warning('登录信息无效，请先登录');
    } else {
      // 如果用户已登录，继续进行路由导航
      next();
    }
  } else {
    // 如果访问的路由不需要身份验证，直接进行路由导航
    next();
  }

  // 如果用户已登录且访问的是登录页面，重定向到首页
  if (token && to.path === '/login') {
    next('/');
  }
});